import re
import random
from flask import request, current_app, jsonify, make_response, session

from info import constants, redis_strict
from info.models import *
from info.utlis.response_code import RET
from info.utlis.captcha.captcha import captcha
from info.modules.passport import passport_blu


# 登陆注册的相关

# 用户退出
@passport_blu.route('/logout', methods=['GET'])
def logout():
    """
    1 删除session缓存
    2 返回
    :return:
    """
    session.pop('user_id', None)
    session.pop('nick_name', None)
    session.pop('mobile', None)
    session.pop('is_admin',False)

    # 返回结果
    return jsonify(errno=RET.OK, errmsg="OK")

#登陆逻辑
@passport_blu.route('/login', methods=['POST'])
def login():
    """
    1 获取数据（电话，密码）
    2 验证信息是否正确
    3 验证电话格式
    4 验证电话号与数据库是否匹配
    5 验证与电话号匹配的密码是否一致
    6 将数据保存到session中，
    7 返回登陆成功
    :return:
    """
    # 获取前端json数据
    login_dict = request.json



    mobile = login_dict.get('mobile')
    password = login_dict.get('password')

    # rel = None
    # 所有是否为空
    if not all([mobile, password]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数不全')

    # 验证电话格式
    if not re.match("1[36458][0-9]{9}", mobile):
        return jsonify(errno=RET.PARAMERR, errmsg='手机号不正确')

    current_app.logger.debug(mobile)

    # 验证电话号与数据库是否一样
    try:

        user = User.query.filter(User.mobile == mobile).first()
    except Exception as e:
        current_app.logger.debug(e)
        return jsonify(errno=RET.DBERR, errmsg="获取本地验证码失败")
    current_app.logger.debug(password)


    # 用户名是否存在
    if not user:
        return jsonify(errno=RET.NODATA, errmsg='用户名不存在')

    # 对比密码
    if not user.check_password(password):
        return jsonify(errno=RET.PWDERR, errmsg='用户或密码不正确')

    # 保存登陆状态到session

    session['user_id'] = user.id
    session['user.mobile'] = user.mobile
    session['user.password_hash'] = user.password_hash

    return jsonify(errno=RET.OK, errmsg='登陆成功')








@passport_blu.route('/register', methods=['POST'])
def register():
    """
    1 获取数据（电话号，短信验证码信息，密码）
    2 判断三个值是否为空
    3 电话号是否为电话号
    4 电话号是否在redis数据库中
    5 验证码是否在redis中
    6 密码是否是正确的
    7 在数据库创建表格
    8 将数据存在session中
    9 返回响应

    :return:
    """
    register_dict = request.json
    # mobile, smscode,password

    mobile = register_dict.get('mobile')
    smscode = register_dict.get('smscode')
    password = register_dict.get('password')
    rel = None
    # 所有是否为空
    if not all([mobile, smscode, password]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数不全')

    # 电话号是否正确
    if not re.match("1[36458][0-9]{9}",mobile):
        return jsonify(errno=RET.PARAMERR, errmsg='手机号不正确')

    # 电话号是否在redis中
    try:
        rel = redis_strict.get("sms" + mobile)
    except Exception as e:
        current_app.logger.debug(e)
        return jsonify(errno=RET.DBERR, errmsg="获取本地验证码失败")

    # 数据库查询验证码是否和参数一致
    if not rel:
        return jsonify(errno=RET.NODATA, errmsg="短信验证码过期")

    # 对比两个验证码
    if smscode != rel:
        return jsonify(errno=RET.DATAERR, errmsg="短信验证码错误")

    # 删除验证码
    try:
        redis_strict.delete("SMS_" + mobile)
    except Exception as e:
        current_app.logger.error(e)

    # 初始化user
    user = User()

    user.mobile = mobile
    user.nick_name = mobile



    # 加密密码
    user.password = password

    try:
        # 添加表单数据
        db.session.add(user)
        db.session.commit()
    except Exception as e:

        current_app.logger.error(e)
        # 操作回滚
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="数据保存失败")

    # 向session添加数据
    session['user_id'] = user.id
    session['user.mobile'] = user.mobile
    session['user.nick_name'] = user.nick_name

    return jsonify(errno=RET.OK, errmsg='注册成功')


@passport_blu.route('/sms_code',methods=['POST'])
def send_sms_code():
    """
    1 获取数据（电话，图片验证码的内容，验证码的随机值）
    2 判断：
        1 所有数据是否为空
        2 手机输入是否正确
        3  验证码的随机值是否redis数据库中有（没有则验证码过期）
        4  验证码的随机值对应的VLUE值是否等于图片验证码的内容
    3 发送短信验证
    4 返回前端发送成功
    :return:
    """
    # 获取post请求的JSON参数request.json
    '{"mobiel": "18811111111", "image_code": "AAAA", "image_code_id": "u23jksdhjfkjh2jh4jhdsj"}'
    params_dict = request.json

    mobile = params_dict.get('mobile') # 获取手机号
    image_code = params_dict.get('image_code') #获取验证码内容
    image_code_id = params_dict.get('image_code_id')  # 获取随机值


    # 判断所有值是否为空
    if not all([mobile,image_code,image_code_id]):
        return jsonify(errno=RET.PARAMERR, errmsg='参数错误')

    if not re.match("1[36458][0-9]{9}",mobile):
        return jsonify(errno=RET.PARAMERR, errmsg='手机号不正确')

    # 抛出异常从redis中取出数据，如果无法取出则表示数据已经过期
    try:
        rel = redis_strict.get("images_code" + image_code_id)
    except Exception as e:
        # 数据库连接失败
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据查询失败")
    # rel返回值为None 则表示key不存在，验证码过期
    if not rel:
        return jsonify(errno=RET.NODATA, errmsg="图片验证码已过期")

    # rel值不等于验证码内容，则表示内容不匹配
    if rel.upper() != image_code.upper():
        return jsonify(errno=RET.DATAERR, errmsg="验证码输入错误")

    # 实现短信验证功能
    mun_random = "%06d"%random.randint(0,9999)
    current_app.logger.debug(mun_random)

    # send_once = CCP().send_template_sms(mobile,[mun_random,constants.SMS_CODE_REDIS_EXPIRES / 60],'1')
    #
    #
    # if send_once != 0:
    #
    #     return jsonify(errno=RET.THIRDERR, errmsg='短信发送失败')
    #     # 发送失败

    # 将短信存在redis中
    try:
        redis_strict.set("sms" + mobile, mun_random, constants.SMS_CODE_REDIS_EXPIRES)
    except Exception as e:
        current_app.logger.error(e)

    # 返回结果
    return jsonify(errno=RET.OK, errmsg="发送成功")







@passport_blu.route('/image_code')
def get_image_code():
    """生成图片验证码
    1 取到参数
    2 判断参数是否有值
    3 生成图片验证码文字内容
    4 保存图片验证码文字内容到redis
    5 返回验证码图片

    """
    # args: 取道url'?'后面的值
    image_code_id = request.args.get('images_code')
    # 导入验证码类   返回三个值
    # 生成图片验证码
    name, text, image = captcha.generate_captcha()




    # 将取道的值储存到redis
    from info import redis_strict
    # 从前端传回来的随机值当作redis的key值，图片生成的验证码内容作为vlue值存入redis
    try:
        # 将值存到redis
        redis_strict.setex("images_code"+image_code_id, constants.IMAGE_CODE_REDIS_EXPIRES, text)


    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DATAERR, errmsg='数据错误')

    current_app.logger.debug(text)

    # 返回响应
    response = make_response(image)
    # 修改数据报头类型
    response.headers['Content-Type'] = 'image/jpg'
    return response



